package org.gdstash.file;

import org.gdstash.db.DBBitmap;
import org.gdstash.db.DBItem;
import org.gdstash.ui.GDStashFrame;
import org.gdstash.util.GDConstants;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.List;

public class ARCList {
    private ListType listType;
    private List<ARCDecompress> list;

    public ARCList(final String dirMod, final List<ARCFile> arcs, final ListType listType) {
        this.listType = ListType.Mixed;
        if (listType == ListType.Text) {
            this.listType = ListType.Text;
        }
        if (listType == ListType.Image) {
            this.listType = ListType.Image;
        }
        this.list = new LinkedList<ARCDecompress>();
        if (dirMod != null && !dirMod.isEmpty()) {
            final File file = new File(dirMod);
            if (file.exists()) {
                File[] files = null;
                if (file.isDirectory()) {
                    files = file.listFiles();
                }
                if (file.isFile()) {
                    files = new File[]{file};
                }
                String modEN = null;
                String modLoc = null;
                ARCDecompress arc = null;
                for (int i = 0; i < files.length; ++i) {
                    try {
                        final String s = files[i].getCanonicalPath();
                        final String t = s.toUpperCase(GDConstants.LOCALE_US);
                        boolean isText = false;
                        boolean doAdd = false;
                        if (t.endsWith(".ZIP")) {
                            isText = true;
                            doAdd = true;
                        }
                        if (t.contains("TEXT_") && t.endsWith(".ARC")) {
                            isText = true;
                            if (t.endsWith("TEXT_EN.ARC")) {
                                modEN = s;
                            }
                            if (GDStashFrame.dbConfig.gdLocal != null && !GDStashFrame.dbConfig.gdLocal.equals("") && t.endsWith(GDStashFrame.dbConfig.gdLocal.toUpperCase(GDConstants.LOCALE_US))) {
                                modLoc = s;
                            }
                        }
                        if (isText) {
                            if (this.listType != ListType.Image && doAdd) {
                                arc = new ARCDecompress(ARCDecompress.FileModule.Mod, s);
                                this.list.add(arc);
                            }
                        } else if (t.endsWith(".ARC") && this.listType != ListType.Text) {
                            arc = new ARCDecompress(ARCDecompress.FileModule.Mod, s);
                            this.list.add(arc);
                        }
                    } catch (IOException ex) {
                    }
                }
                if (modLoc == null) {
                    modLoc = modEN;
                }
                if (modLoc != null) {
                    arc = new ARCDecompress(ARCDecompress.FileModule.Mod, modLoc);
                    this.list.add(arc);
                }
            }
        }
        if (arcs != null) {
            for (final ARCFile arcFile : arcs) {
                if (arcFile == null) {
                    continue;
                }
                if (arcFile.filename == null) {
                    continue;
                }
                final String t2 = arcFile.filename.toUpperCase(GDConstants.LOCALE_US);
                if (t2.endsWith(".ZIP") || (t2.contains("TEXT_") && t2.endsWith(".ARC"))) {
                    if (this.listType == ListType.Image) {
                        continue;
                    }
                    final ARCDecompress arc2 = new ARCDecompress(arcFile.module, arcFile.filename);
                    this.list.add(arc2);
                } else {
                    if (!t2.endsWith(".ARC") || this.listType == ListType.Text) {
                        continue;
                    }
                    final ARCDecompress arc2 = new ARCDecompress(arcFile.module, arcFile.filename);
                    this.list.add(arc2);
                }
            }
        }
    }

    public void decompress() {
        for (final ARCDecompress arc : this.list) {
            arc.decompress(null);
        }
    }

    public void writeFiles(final String dir, final boolean writeVanilla) {
        for (final ARCDecompress arc : this.list) {
            final String fn = arc.getFileName();
            int pos = fn.indexOf(GDConstants.FILE_SEPARATOR + "mods" + GDConstants.FILE_SEPARATOR);
            if (pos == -1 && !writeVanilla) {
                continue;
            }
            pos = fn.lastIndexOf(GDConstants.FILE_SEPARATOR);
            if (pos == -1) {
                pos = 0;
            }
            String subdir = fn.substring(pos);
            subdir = subdir.substring(0, subdir.length() - 4).toLowerCase();
            arc.writeFiles(dir, subdir);
        }
    }

    public void updateImageData() {
        for (final ARCDecompress arc : this.list) {
            arc.updateImageData(null);
        }
        DBBitmap.deleteNoImageBitmaps();
        DBItem.deleteNoImageItems();
    }

    public String getTag(final ARCDecompress.FileModule module, final String filename, final String tag, final boolean insertColor) {
        final String[] filenames = {filename};
        return this.getTag(module, filenames, tag, insertColor);
    }

    public String getTag(final ARCDecompress.FileModule module, final String[] filenames, final String tag, final boolean insertColor) {
        if (tag == null) {
            return null;
        }
        final List<String> listFN = new LinkedList<String>();
        for (int i = 0; i < filenames.length; ++i) {
            listFN.add(filenames[i]);
        }
        String result = null;
        if (module == ARCDecompress.FileModule.All) {
            for (final ARCDecompress arc : this.list) {
                result = arc.getTag(listFN, tag, insertColor);
                if (result != null) {
                    break;
                }
            }
        } else {
            for (final ARCDecompress arc : this.list) {
                if (module != arc.getModule()) {
                    continue;
                }
                result = arc.getTag(listFN, tag, insertColor);
                if (result != null) {
                    break;
                }
            }
            if (result == null) {
                for (final ARCDecompress arc : this.list) {
                    if (module == arc.getModule()) {
                        continue;
                    }
                    result = arc.getTag(listFN, tag, insertColor);
                    if (result != null) {
                        break;
                    }
                }
            }
        }
        if (result != null) {
            final ByteBuffer buffer = StandardCharsets.UTF_8.encode(result);
            final String utf8 = result = StandardCharsets.UTF_8.decode(buffer).toString();
        }
        return result;
    }

    public enum ListType {
        Image,
        Text,
        Mixed;
    }

    public static class ARCFile {
        public ARCDecompress.FileModule module;
        public String filename;

        public ARCFile(final ARCDecompress.FileModule module, final String filename) {
            this.module = module;
            this.filename = filename;
        }
    }
}
